package Groups;

import java.util.Random;

import Population.*;

public abstract class Group {
	String groupType="";
	String name = "";
	public boolean toBeRemoved = false;
	
	Inhabitant leader;
	Inhabitant[] members;
	
	int foodSupply = 0;
	
	public Group(Inhabitant[] founders, String gType)
	{
		members = new Inhabitant[0];
		Random rGen = new Random();
		leader = founders[rGen.nextInt(founders.length)];  // Leader doesn't mean anything for Wanderers
		System.out.println("newLeader = "+leader.getID());
		
		for (int i=0; i<founders.length; i++)
		{
			if(founders[i].getID() != leader.getID())
				AddMember(founders[i]);
		}
		groupType = gType;
		name = GenerateGroupName();
	}
	
	public abstract void Update();
//	{
//		for(int i=0; i<members.length; i++)
//			members[i].AI();
//	}
	
	/**
	 * Randomly chooses a leader
	 */
	public void ElectLeader()
	{  // Choose the leader then remove him from the list of members
		if(members.length != 0)
		{
			Random rGen = new Random();
			leader = members[rGen.nextInt(members.length)];
			boolean seen = false;
			Inhabitant[] temp = new Inhabitant[members.length];
			int count = 0;

				for(int i =0; i<members.length; i++)
				{
					if(members[i].getID() != leader.getID())
					{
						temp[count] = members[i];
						count++;
					}
					else
					{
						seen = true;
						members[i].setGroupName("");
					}
				}
				if(seen)
				{
					ReallocateMemberArray(count);
					for (int i=0; i<count; i++)
					{
						members[i] = temp[i];
					}
				}
			}
			name = leader.getID() + "'s "+groupType;

	}
	
	/**
	 * Adds a member to the members array if they are not already in the list
	 * @param newMember
	 */
	public void AddMember(Inhabitant newMember)
	{
		boolean seen = false;
		for(int i=0; i<members.length; i++)
		{
			if(members[i].getID() == newMember.getID())
			{
				seen = true;
			}
		}
		if(!seen)
		{
			ReallocateMemberArray(members.length+1);
			members[members.length-1] = newMember;
			newMember.setGroupName(groupType);
		}
	}
	
	/**
	 * Adds a list of members to the members array
	 * @param newMember
	 */
	public void AddMembers(Inhabitant[] newMember)
	{
		boolean seen = false;
		for(int j=0; j<newMember.length; j++)
		{
			for(int i=0; i<members.length; i++)
			{
				if(members[i].getID() == newMember[j].getID())
				{
					seen = true;
				}
			}
			if(!seen)
			{
				ReallocateMemberArray(members.length+1);
				members[members.length-1] = newMember[j];
				newMember[j].setGroupName(groupType);
			}
		}
	}
	
	/**
	 * Removes a member from members
	 * @param member
	 */
	public void RemoveMember(Inhabitant member)
	{
		boolean seen = false;
		Inhabitant[] temp = new Inhabitant[members.length];
		int count = 0;
		if(member.getID() == leader.getID())
		{
			ElectLeader();
		}
		else
		{
			for(int i =0; i<members.length; i++)
			{
				if(members[i].getID() != member.getID())
				{
					temp[count] = members[i];
					count++;
				}
				else
				{
					seen = true;
					members[i].setGroupName("");
				}
			}
			if(seen)
			{
				ReallocateMemberArray(count);
				for (int i=0; i<count; i++)
				{
					members[i] = temp[i];
				}
			}
		}
	}
	
	/**
	 * Removes a list of members from members
	 * @param member
	 */
	public void RemoveMembers(Inhabitant[] member)
	{
		boolean seen = false;
		Inhabitant[] temp = new Inhabitant[members.length - 1];
		int count = 0;
		for(int j = 0; j<member.length; j++)
		{
			for(int i =0; i<members.length; i++)
			{
				if(members[i].getID() != member[j].getID())
				{
					temp[count] = members[i];
					count++;
				}
				else
				{
					seen = true;
					members[i].setGroupName("");
				}
			}
			
			if (seen)
			{
				ReallocateMemberArray(count);
				for (int i=0; i<count; i++)
				{
					members[i] = temp[i];
				}
			}
		}
	}
	
	/**
	 * Moves the group
	 */
	public abstract void Move();
	// Defined for the sub classes.  A roaming band will move differently than a settlement
	
	/**
	 * Generates the name for the group
	 * @return
	 */
	public abstract String GenerateGroupName();
	
	/**
	 * Completely disbands the group.
	 */
	public void Disband()
	{
		toBeRemoved = true;
	}
	
	/**
	 * Reallocates the member array to a new length
	 * @param length
	 */
	public void ReallocateMemberArray(int length)
	{
		if(length != 0)
		{
			Inhabitant[] tempInhab = new Inhabitant[length];
			if(members.length < length)
			{
				for (int i =0; i<members.length; i++)
				{
					tempInhab[i] = members[i];
				}
				members = new Inhabitant[length];
				for (int i =0; i<members.length; i++)
				{
					members[i] = tempInhab[i];
				}
			}
			else if ( length < members.length)
			{
				int count = 0;
				for (int i =0; i<members.length; i++)
				{
					if(members[i].isAlive)
					{
						tempInhab[count] = members[i];
						count++;
					}
					if(count == length)
						break;
				}
				members = new Inhabitant[length];
				for (int i =0; i<members.length; i++)
				{
					members[i] = tempInhab[i];
				}
			}
		}
		else
		{
			members = new Inhabitant[0];
		}
	}
	
	/**
	 * Ages the entire group.  May not be necessary.
	 */
	public void AgeGroup()
	{
		for(int i=0; i<members.length; i++)
		{
			members[i].incAge();
		}
	}
	
	/**
	 * Returns a string of the group information
	 * @return
	 */
	public String ReportGroup()
	{
		String message = "";
		message = "          < Group: "+name+" >          \n";
		int length = message.length();
		for(int i=0; i<length; i++)
		{
			message = message + "*";
		}
		message = message + "\n";
		message = message + "Leader:"+leader.getID()+"\n";
		for(int i=0; i<members.length; i++)
		{
			message = message + "Member "+i+":"+ members[i].getID() + "\n";
		}
		return message;
	}
	
	public abstract int GetReqTriggerSize();
	
	public abstract int GetReqTriggerTime();
	
	
	public boolean contains(Inhabitant memberToSearchFor)
	{
		return false;
	}
}
